package tools.canal;

import java.net.*;
import java.io.*; //import java.util.*;
//import tools.command.*;
import tools.command.commandInterface.*;

/**
 * @author rapha Abstração do canal de comunicações
 */
public class Canal {

	/**
	 * Declarações iniciais
	 */
	private String host;
	private int port;
	private Socket connection;
	private ServerSocket socket1;
	InetAddress address;
	BufferedOutputStream bos;
	ObjectOutputStream osw;
	BufferedInputStream is;
	ObjectInputStream isr;

	/**
	 * @param host
	 *            - Endereço de destino da conexão
	 * @param port
	 *            - Porto a ser utilizado Construtor do canal
	 */
	public Canal(String host, int port) {
		this.host = host;
		this.port = port;
	}

	/**
	 * Função para abrir conexão quando se é cliente
	 */
	public void openConnectionClient() {
		// Open a new connection:
		try {
			address = InetAddress.getByName(host);
			connection = new Socket(address, port);
			osw = new ObjectOutputStream(connection.getOutputStream());
			isr = new ObjectInputStream(connection.getInputStream());
		} catch ( IOException e) {
			System.out.println("Conexão recusada");
			e.printStackTrace();
			System.exit(1);
		}
	}

	/**
	 * Função para abrir conexão quando se é Servidor
	 */
	public void openConnectionServer() {
		// Open a new connection:
		try {
			socket1 = new ServerSocket(port);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Função utilizado por servidores para esperar pelo proxima requisição
	 */
	public void serverProximo() {
		// Open a new connection:
		try {
			this.connection = socket1.accept();
			osw = new ObjectOutputStream(connection.getOutputStream());
			isr = new ObjectInputStream(connection.getInputStream());

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Função para fechar conexão
	 */
	public void closeConnection() {
		// Close the connection:
		try {
			osw.flush();
			connection.close();
			osw.close();
			isr.close();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param envio
	 *            - Command a ser enviado Função para envio de command
	 */
	public void escreve(Command envio) {

		try {

			System.out.println("Tentando enviar");
			osw.writeObject(envio);
			osw.flush();
			System.out.println("Command enviado");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @return Commando enviado Função para recebimento de command
	 */
	public Command recebe() {

		try {

			Command comando = (Command) isr.readObject();
			System.out.println("Object's Class name =>"
					+ comando.getClass().getName());
			System.out.println("Recebi um Command");

			return comando;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
